﻿using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using Comissoes.Models;
using System;
using System.Collections.Generic;
using Comissoes.JQGridObject;
using Comissoes.Controllers;

namespace Comissoes.Controllers
{
    public class EnderecosController : AppController
    {
        xcontEntities db = new xcontEntities();

        public JsonResult PessoaIdSearch(int? ID_ENPS)
        {
            if (ID_ENPS.HasValue)
            {
                return Json(from c in db.ENDERECOS_PESSOA
                            where c.ID_ENPS == ID_ENPS
                            select new
                            {
                                c.ENDERECOS.LOGRADOUROS.NOME_LOGRAD,
                                c.ENDERECOS.LOGR_END,
                                c.NUMERO_ENPS,
                                c.ENDERECOS.BAIRROS.CIDADES.NOME_CID,
                                c.ENDERECOS.BAIRROS.CIDADES.UFS.SIGLA_UF
                            }, JsonRequestBehavior.AllowGet);
            }

            return Json(string.Empty, JsonRequestBehavior.AllowGet);
        }

        // Busca os dados de um endereço pelo CEP
        public JsonResult CepSearch(string CEP_END)
        {
            CEP_END = CEP_END.Replace("-", string.Empty);
            var enderecos = (from c in db.ENDERECOS
                             where c.CEP_END == CEP_END
                             orderby c.LOGR_END
                             select new
                             {
                                 c.ID_END,
                                 c.LOGRADOUROS.ID_LOGRAD,
                                 c.LOGRADOUROS.NOME_LOGRAD,
                                 c.LOGR_END,
                                 c.CEP_END,
                                 c.BAIRROS.ID_BAIRRO,
                                 c.BAIRROS.NOME_BAIRRO,
                                 c.BAIRROS.CIDADES.ID_CID,
                                 c.BAIRROS.CIDADES.NOME_CID,
                                 c.BAIRROS.CIDADES.UFS.ID_UF,
                                 c.BAIRROS.CIDADES.UFS.SIGLA_UF
                             }).FirstOrDefault();
            if (enderecos == null)
            {
                return Json(false, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(enderecos, JsonRequestBehavior.AllowGet);
            }
        }

        // Busca as cidades de um estado e/ou sugestão
        public JsonResult CidadeSearch(Int32? ID_UF, Int32? CODIBGE_UF,String SIGLA_UF)
        {
            if (ID_UF.HasValue)
            {
                var cidades = from c in db.CIDADES
                              where c.UFS.ID_UF == ID_UF
                              orderby c.NOME_CID
                              select new
                              {
                                  c.ID_CID,
                                  c.NOME_CID
                              };

                return Json(cidades, JsonRequestBehavior.AllowGet);
            }
            if (CODIBGE_UF.HasValue)
            {
                var cidades = from c in db.CIDADES
                              where c.UFS.CODIBGE_UF == CODIBGE_UF
                              orderby c.NOME_CID
                              select new
                              {
                                  c.CODIBGE_CID,
                                  c.NOME_CID
                              };

                return Json(cidades, JsonRequestBehavior.AllowGet);
            }
            if (!String.IsNullOrEmpty(SIGLA_UF))
            {
                var cidades = from c in db.CIDADES
                              where c.UFS.SIGLA_UF == SIGLA_UF
                              orderby c.NOME_CID
                              select new
                              {
                                  c.ID_CID,
                                  c.NOME_CID
                              };

                return Json(cidades, JsonRequestBehavior.AllowGet);
            }

            return Json(string.Empty, JsonRequestBehavior.AllowGet);
        }

        // Busca os bairros de uma cidade e/ou sugestão
        public JsonResult BairroSearch( Int32? ID_CID)
        {
            if (ID_CID.HasValue)
            {
                var bairros = from c in db.BAIRROS
                              where c.CIDADES.ID_CID == ID_CID
                              orderby c.NOME_BAIRRO
                              select new
                              {
                                  c.ID_BAIRRO,
                                  c.NOME_BAIRRO
                              };

                return Json(bairros, JsonRequestBehavior.AllowGet);
            }

            return Json(string.Empty, JsonRequestBehavior.AllowGet);
        }


        public ActionResult TiposEndereco()
        {
            return View();
        }

        // Cria a lista de tipos de endereço
        public ActionResult TiposEnderecoList(string sidx, string sord, int page, int rows, bool _search, string searchField, string searchOper, string searchString)
        {
            var q = from c in db.TIPOS_ENDERECO
                    select new
                    {
                        c.ID_TPEN,
                        c.DESC_TPEN
                    };

            JQGridBuilder jbuilder = new JQGridBuilder(q, page, sidx, sord, searchField, searchString, searchOper, "ID_TPEN", _search, rows);

            return Json(jbuilder.GetObject(), JsonRequestBehavior.AllowGet);
        }

        // Exibe detalhes do histórico
        public ActionResult TipoEnderecoDetails( int ID_TPEN)
        {
            return View(db.TIPOS_ENDERECO.FirstOrDefault(t => t.ID_TPEN == ID_TPEN));
        }

        // Altera os dados do tipo de endereço
        public ActionResult TipoEnderecoUpdate( TIPOS_ENDERECO endereco)
        {
            List<string> erros = new List<string> { };

            // Verifica se a descrição foi informada
            if (string.IsNullOrEmpty(endereco.DESC_TPEN))
                erros.Add("É necessário informar a descrição do tipo de endereço.");

            else if (db.TIPOS_ENDERECO.Any(t => t.DESC_TPEN == endereco.DESC_TPEN))
                erros.Add("Tipo de endereço já cadastrado.");

            if(!erros.Any())
            try
            {
                UpdateModel(db.TIPOS_ENDERECO.FirstOrDefault(t => t.ID_TPEN.Equals(endereco.ID_TPEN)));
                db.SaveChanges();

                return RedirectToAction("TipoEnderecoDetails", new { ID_TIPOEND = endereco.ID_TPEN });
            }
            catch (Exception ex)
            {
                erros.Add(ex.Message);
            }

            return RedirectToAction("Error", "Default", new { erros = erros });
        }

        // Exclui um tipo de endereço
        public ActionResult TipoEnderecoDelete(Int32? ID_TPEN)
        {
            List<string> erros = new List<string>();

            if (db.ENDERECOS_PESSOA.Any(t => t.TIPOS_ENDERECO.ID_TPEN == ID_TPEN))
                erros.Add("Existem endereços cadastrados com este tipo no momento.");

            if (!erros.Any())
            {
                try
                {
                    db.DeleteObject(db.TIPOS_ENDERECO.FirstOrDefault(t => t.ID_TPEN == ID_TPEN));
                    db.SaveChanges();
                }
                catch (Exception ex)
                {
                    erros.Add(ex.Message);
                }
            }

            return Json(erros, JsonRequestBehavior.AllowGet);
        }

        public ActionResult LookupList(int? ID_CID, String term)
        {
            return Json((from c in db.ENDERECOS.Include("BAIRROS").Include("BAIRROS.CIDADES")
                         where (c.LOGR_END.ToUpper().Contains(term.ToUpper()))
                         && (ID_CID == null ? true : c.BAIRROS.CIDADES.ID_CID == ID_CID)
                         orderby c.LOGR_END
                         select new
                         {
                             id = c.CEP_END,
                             label = c.LOGRADOUROS.NOME_LOGRAD + " " + c.LOGR_END + " - " + c.BAIRROS.NOME_BAIRRO,
                             value = c.LOGR_END,
                             c.ID_END,
                             c.LOGRADOUROS.ID_LOGRAD,
                             c.BAIRROS.ID_BAIRRO
                         }).Take(10), JsonRequestBehavior.AllowGet);
        }

        // Retorna a partial de edição do endereço
        public ActionResult Edit(Int32? id)
        {
            if (id.HasValue)
            {
                ENDERECOS_PESSOA e = db.ENDERECOS_PESSOA.Include("PESSOAS")
                                                        .Include("ENDERECOS")
                                                        .Include("TIPOS_ENDERECO")
                                                        .Include("ENDERECOS.LOGRADOUROS")
                                                        .Include("ENDERECOS.BAIRROS")
                                                        .Include("ENDERECOS.BAIRROS.CIDADES")
                                                        .Include("ENDERECOS.BAIRROS.CIDADES.UFS")
                                                        .FirstOrDefault(t => t.ID_ENPS == id);

                ViewData["IDTPEN"] = new SelectList(db.TIPOS_ENDERECO, "ID_TPEN", "DESC_TPEN", e.TIPOS_ENDERECO.ID_TPEN);
                ViewData["IDLOGRAD"] = new SelectList(db.LOGRADOUROS, "ID_LOGRAD", "NOME_LOGRAD", e.ENDERECOS.LOGRADOUROS.ID_LOGRAD);
                ViewData["IDUF"] = new SelectList(db.UFS, "ID_UF", "SIGLA_UF", e.ENDERECOS.BAIRROS.CIDADES.UFS.ID_UF);
                ViewData["IDCID"] = new SelectList(db.CIDADES.Where(t => t.UFS.ID_UF == e.ENDERECOS.BAIRROS.CIDADES.UFS.ID_UF), "ID_CID", "NOME_CID", e.ENDERECOS.BAIRROS.CIDADES.ID_CID);
                ViewData["IDBAIRRO"] = new SelectList(db.BAIRROS.Where(t => t.CIDADES.ID_CID == e.ENDERECOS.BAIRROS.CIDADES.ID_CID), "ID_BAIRRO", "NOME_BAIRRO", e.ENDERECOS.BAIRROS.ID_BAIRRO);

                return PartialView(e);
            }
            else
            {
                ViewData["IDTPEN"] = new SelectList(db.TIPOS_ENDERECO, "ID_TPEN", "DESC_TPEN");
                ViewData["IDLOGRAD"] = new SelectList(db.LOGRADOUROS, "ID_LOGRAD", "NOME_LOGRAD");
                ViewData["IDUF"] = new SelectList(db.UFS, "ID_UF", "SIGLA_UF");
                ViewData["IDCID"] = new SelectList(new Dictionary<string, string>());
                ViewData["IDBAIRRO"] = new SelectList(new Dictionary<string, string>());

                return PartialView(new ENDERECOS_PESSOA { ENDERECOS = new ENDERECOS() });
            }
        }

        //  Confirma a inclusão do endereço
        public ActionResult Update(Int32? type, Int32? COD_PESSOA, Int32? ID_PESSOA, Int32? ID_ENPS, Int32? ID_TPEN, Int32? ID_UF, Int32? ID_CID, Int32? ID_BAIRRO, String NOME_BAIRRO, Int32? ID_LOGRAD, Int32? ID_END, String LOGR_END, String CEP_END, String NUMERO_END, String COMPL_END)
        {
            List<string> erros = new List<string>();

            if (string.IsNullOrEmpty(CEP_END)) erros.Add("É necessário informar o CEP.");
            if (string.IsNullOrEmpty(NUMERO_END)) erros.Add("É necessário informar o número.");
            if (!ID_TPEN.HasValue) erros.Add("É necessário informar o tipo do endereço.");
            if (!ID_UF.HasValue) erros.Add("É necessário informar o estado.");
            if (!ID_CID.HasValue) erros.Add("É necessário informar a cidade.");
            if (string.IsNullOrEmpty(LOGR_END)) erros.Add("É necessário informar o endereço.");

            if (!erros.Any())
            {
                try
                {
                    ENDERECOS endereco;
                    BAIRROS bairro;

                    if (ID_BAIRRO.HasValue)
                    {
                        bairro = db.BAIRROS.FirstOrDefault(t => t.ID_BAIRRO == ID_BAIRRO);
                    }
                    else
                    {
                        bairro = new BAIRROS
                        {
                            CIDADES = db.CIDADES.FirstOrDefault(t => t.ID_CID == ID_CID)
                        };
                        db.AddToBAIRROS(bairro);
                    }

                    if (!String.IsNullOrEmpty(NOME_BAIRRO))
                    {
                        bairro.NOME_BAIRRO = NOME_BAIRRO;
                    }
                    db.SaveChanges();

                    if (ID_END.HasValue && ID_END != 0)
                    {
                        endereco = db.ENDERECOS.FirstOrDefault(t => t.ID_END == ID_END);
                    }
                    else
                    {
                        endereco = new ENDERECOS
                        {
                            LOGR_END = LOGR_END,
                            CEP_END = CEP_END.Replace("-", ""),
                            BAIRROS = bairro,
                            LOGRADOUROS = db.LOGRADOUROS.FirstOrDefault(t => t.ID_LOGRAD == ID_LOGRAD)
                        };
                        db.AddToENDERECOS(endereco);
                        db.SaveChanges();
                    }

                    ENDERECOS_PESSOA enps;
                    if (ID_ENPS.HasValue && ID_ENPS != 0)
                        enps = db.ENDERECOS_PESSOA.FirstOrDefault(t => t.ID_ENPS == ID_ENPS);
                    else
                    {
                        PESSOAS pessoa;
                        if (type.HasValue)
                        {
                            switch (type)
                            {
                                case 1:
                                case 4:
                                    pessoa = db.LOJAS.Include("PESSOAS").FirstOrDefault(t => t.COD_LOJA == ID_PESSOA).PESSOAS;
                                    break;
                                case 2:
                                case 5:
                                    pessoa = db.CLIENTES.Include("PESSOAS").FirstOrDefault(t => t.COD_CLI == ID_PESSOA).PESSOAS;
                                    break;
                                case 3:
                                    pessoa = db.TRANSPORTADORES.Include("PESSOAS").FirstOrDefault(t => t.COD_TRAN == ID_PESSOA).PESSOAS;
                                    break;
                                default:
                                    pessoa = new PESSOAS();
                                    break;
                            }
                        }
                        else
                        {
                            pessoa = db.PESSOAS.FirstOrDefault(t => t.ID_PESSOA == ID_PESSOA);
                        }

                        enps = new ENDERECOS_PESSOA { PESSOAS = pessoa };
                        db.AddToENDERECOS_PESSOA(enps);
                    }

                    enps.ENDERECOS = endereco;
                    enps.NUMERO_ENPS = NUMERO_END;
                    enps.COMPL_ENPS = COMPL_END;
                    enps.TIPOS_ENDERECO = db.TIPOS_ENDERECO.FirstOrDefault(t => t.ID_TPEN == ID_TPEN);

                    db.SaveChanges();

                    return Json(new { result = true, value = enps.ID_ENPS }, JsonRequestBehavior.AllowGet);
                }
                catch (Exception ex)
                {
                    erros.Add(ex.Message);
                }
            }

            return Json(new { result = false, erros = erros }, JsonRequestBehavior.AllowGet);
        }
    }
}